package insulinpumpsimulation;

import insulinpumpsimulation.com.his.audiocontrol.SoundAlert;
import insulinpumpsimulation.com.his.literal.InsulinPumpLiterals;
import insulinpumpsimulation.com.his.tasks.BasalManager;
import insulinpumpsimulation.com.his.tasks.BolusManager;
import insulinpumpsimulation.com.his.tasks.UpdateSimulatorTask;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.Timer;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;

/**
 *
 * @author Sabahul Hassan
 */
public class SimulationController implements Initializable {
    
    
    private static SoundAlert speak=null;
    private static String path;
    // Return the Object of this class
    private static SimulationController uiController;
    // SET refresh interval for Simulator
    private int simulationInterval = InsulinPumpLiterals.SIMULATION_INTERVAL;
    // Reservoir Progress Bar
    @FXML
    private ProgressBar ins_Res_ProgBar;
    
    @FXML
    private ImageView imgView;
    
    @FXML
    private ImageView imgViewGreen;
    
    // Reservoir Label to show percentage after Progress Bar
    @FXML
    private Label ins_Res_Percentage;
    /**
     * Battery Stuff
     */
    // Battery Progress Bar
    @FXML
    private ProgressBar ins_Batt_ProgBar;
    // Battery Label
    @FXML
    private Label ins_Batt_Percentage;
    @FXML
    private TextArea ins_Msg_Area;
    @FXML
    final NumberAxis sugarLevelYAxis = new NumberAxis();
    @FXML
    final NumberAxis timeXAxis = new NumberAxis();
    @FXML
    final LineChart<Number, Number> ins_Graph = new LineChart<Number, Number>(timeXAxis, sugarLevelYAxis);
    @FXML
    private ComboBox ins_Combo_Food = new ComboBox();
    @FXML
    private TextField ins_txtBox_Manual;
    @FXML
    private AnchorPane ancorPane;
    @FXML
    private Label ins_Clock;
     @FXML
    private CheckBox ins_chBox_Needle;
      @FXML
    private CheckBox ins_chBox_Sensor;
       @FXML
    private CheckBox ins_chBox_Excercise;
    
    // Get Instance of this class

    public static SimulationController getInstance() {
        return uiController;
    }
    @FXML
    private void needleAction(ActionEvent event) {
        ins_chBox_Needle.selectedProperty().addListener(new ChangeListener<Boolean>() {
           @Override
           public void changed(ObservableValue<? extends Boolean> ov,
             Boolean old_val, Boolean new_val) {
             if(ins_chBox_Needle.isSelected())
             {
                 setIns_Msg_Area("Please insert the needle !!!");
             }
             else{
                 setIns_Msg_Area("");
             }
          }
        });
    }
    @FXML
    private void sensorAction(ActionEvent event) {
        ins_chBox_Sensor.selectedProperty().addListener(new ChangeListener<Boolean>() {
           @Override
           public void changed(ObservableValue<? extends Boolean> ov,
             Boolean old_val, Boolean new_val) {
             if(ins_chBox_Sensor.isSelected())
             {
                 setIns_Msg_Area("Sensor is not Working !!!");
             }
             else{
                 setIns_Msg_Area("");
             }
          }
        });
    }
    @FXML
    private void excerciseAction(ActionEvent event) {
        ins_chBox_Excercise.selectedProperty().addListener(new ChangeListener<Boolean>() {
            BasalManager basalManager = new BasalManager();
           @Override
           public void changed(ObservableValue<? extends Boolean> ov,
             Boolean old_val, Boolean new_val) {
             if(ins_chBox_Excercise.isSelected())
             {
                 setIns_Msg_Area_Success("Excercise Mode is Activated. Your basal input is reduced to half!!!");
                 basalManager.setExcerciseMode(true);
             }
             else{
                 setIns_Msg_Area_Success("");
                 basalManager.setExcerciseMode(false);
             }
          }
        });
    }
    // Action for clearing message area
     @FXML
    private void clearAction(ActionEvent event) {
            setIns_Msg_Area("");
            removeImgViewRed("yeah");
    }
    
    // Action for submit button for Food intake and Manual Entry
    @FXML
    private void submitButtonAction(ActionEvent event) {
        try {
            String item = ins_Combo_Food.getValue().toString();
            String manualEntry = "";
        
            if (item.equalsIgnoreCase("Manual Entry"))
            {
                manualEntry = ins_txtBox_Manual.getText();
            }
            
            final double bolusQuantity =  BolusManager.menuItems(item,manualEntry);
            UpdateSimulatorTask.res_Prog = UpdateSimulatorTask.res_Prog - bolusQuantity;
        } catch (NullPointerException npe) {
            setIns_Msg_Area("Please select a value from DropDown or Enter number for in textbox for manual entry !");
        }

    }
    
    //
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        setValuesInComboBox();
        ancorPane.setStyle("-fx-background-color:lightblue");
        uiController = this;
        Timer timer = new Timer();
        timer.schedule(new UpdateSimulatorTask(), 0, simulationInterval);



    } // END OF initialize()    

    // Setting Error Messages and Notification in the ins_Msg_Area
    public void setIns_Msg_Area(String txtMessage) {
        this.ins_Msg_Area.setText(txtMessage);
        ins_Msg_Area.setStyle("-fx-text-fill: red;-fx-highlight-fill: lightgray; -fx-highlight-text-fill: firebrick; -fx-font-size: 18px;");
    }

    public void setIns_Msg_Area_Success(String txtMessage) {
        this.ins_Msg_Area.setText(txtMessage);
        ins_Msg_Area.setStyle("-fx-text-fill: green;");
    }

    // Setting Reservoir Progress Bar
    public void setIns_Res_ProgBar(double simulationInterval) {
        
        
        if (simulationInterval < 0) {
            simulationInterval = 0;
        }

        if (simulationInterval < .10) {
            setIns_Msg_Area("The resevoir level is below 10 %. Please refill the insulin !");
            setImgViewRed("ok");
          path="resources/resources/InsulinReservoirLevel_LOW.wav";     
          speak=new SoundAlert(path);
          speak.start();
          speak.stop();
        }
        final double locSimulationInterval = simulationInterval;
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                ins_Res_ProgBar.setProgress(locSimulationInterval);
            }
        });
    }

    // setting image
    public void setImgViewRed(String one){
//        path="resources/resources/InsulinReservoirLevel_LOW.wav";     
//        Image image1 = new Image("file:///RedLedTransparent.png");
        javafx.scene.image.Image image = new javafx.scene.image.Image(getClass().getResource("RedLedTransparent.png").toExternalForm());
        
        imgView.setImage(image);
        imgView.setVisible(true);
    }
    
    
    // setting image
    public void removeImgViewRed(String one){
//        path="resources/resources/InsulinReservoirLevel_LOW.wav";     
//        Image image1 = new Image("file:///RedLedTransparent.png");
        javafx.scene.image.Image image = new javafx.scene.image.Image(getClass().getResource("RedLedTransparent.png").toExternalForm());
        
        imgView.setImage(image);
        imgView.setVisible(false);
    }
    
    
    // setting image
    public void setImgViewGreen(String one){
//        path="resources/resources/InsulinReservoirLevel_LOW.wav";     
//        Image image1 = new Image("file:///RedLedTransparent.png");
        javafx.scene.image.Image image = new javafx.scene.image.Image(getClass().getResource("GreenLedTransparent.png").toExternalForm());
        
        imgViewGreen.setImage(image);
    }
    
    public void setIns_Res_Percentage(String reservoirPercentage) {
         if (reservoirPercentage.charAt(0)=='-') {
           reservoirPercentage = "0";
        }
        final String locReservoirPercentage = reservoirPercentage;
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                ins_Res_Percentage.setText(locReservoirPercentage);
            }
        });
    }

    // Setting Reservoir Progress Bar
    public void setIns_Batt_ProgBar(double batteryProgress) {
        ins_Batt_ProgBar.setProgress(batteryProgress);
    }

    /**
     *
     * @param batteryProgress
     */
    public void setValuesInComboBox() {
        ins_Combo_Food.getItems().addAll();
    }

    public void setIns_Graph(double timeNa, int sugarA) {
        
        validateSugarLevel(sugarA);
        //populating the series with data
        final Number timeN = timeNa;
        final Number sugar = sugarA;
        final XYChart.Series<Number, Number> series = new XYChart.Series<>();
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                timeXAxis.setLabel("Time");
                sugarLevelYAxis.setLabel("Sugar Level");
                series.getData().add(new XYChart.Data<Number, Number>(timeN, sugar));
                ins_Graph.getData().add(series);
            }
        });
    }

    public void setIns_Batt_Percentage(String batteryPercentage) {

        final String locBatteryPercentage = batteryPercentage;
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                ins_Batt_Percentage.setText(locBatteryPercentage);
            }
        });
    }
    
    public void setIns_Clock(String time) {
        //populating the series with data

        final String locTime = time; 
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                ins_Clock.setText(locTime);
            }
        });
    }
    
    public void validateSugarLevel(int sugarLevel)
    {
        if (sugarLevel > 130)
        {
            Double amountOfInsulinRequired = (sugarLevel - 105)*0.018;
            setIns_Msg_Area("Your Blood sugar Level is very High. We suggest you to take "+amountOfInsulinRequired.floatValue()+" units of insulin !");
            setImgViewRed("ok");
          path="resources/resources/Hyper.wav";     
          speak=new SoundAlert(path);
          speak.start();
          speak.stop();
            
        }
        else if (sugarLevel < 70)
        {
           setIns_Msg_Area("Your Blood sugar Level is very low. Please have a fast acting sugar food like 1/2 cup orange juice !");
           setImgViewRed("ok");
          path="resources/resources/Hypo.wav";     
          speak=new SoundAlert(path);
          speak.start();
          speak.stop(); 
        }
    }
    
    public void setIns_txtBox_Manual(String txtMessage) {
        ins_txtBox_Manual.setText(txtMessage);
    }
}
